package com.tanhua.api.mongo;

import cn.hutool.core.collection.CollectionUtil;
import com.tanhua.domain.mongo.*;
import com.tanhua.domain.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.List;

@Service
public class PublishApiImpl implements PublishApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;

    @Override
    public void save(Publish publish) {
        // 1、保存动态详情
        publish.setCreated(System.currentTimeMillis()); // 指定时间
        publish.setPid(idService.getNextId("quanzi_publish")); // 指定pid
        mongoTemplate.save(publish);
        // 2、保存个人动态
        Album album = new Album();
        album.setPublishId(publish.getId()); // 动态id
        album.setCreated(System.currentTimeMillis()); // 指定时间
        mongoTemplate.save(album, "quanzi_album_" + publish.getUserId()); // 指定表名

        // 3、查询好友
        Query query = new Query(
                Criteria.where("userId").is(publish.getUserId())
        );
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);

        if (friendList != null) {
            for (Friend friend : friendList) {
                // 4、保存好友动态
                TimeLine timeLine = new TimeLine();
                timeLine.setUserId(publish.getUserId()); // 发布人id
                timeLine.setPublishId(publish.getId());// 动态id
                timeLine.setCreated(System.currentTimeMillis()); // 时间
                mongoTemplate.save(timeLine, "quanzi_time_line_" + friend.getFriendId());
            }
        }

    }

    @Override
    public PageBeanVo findAlbumByPage(Integer pageNum, Integer pageSize, Long userId) {

        Integer index = (pageNum - 1) * pageSize;
        // 1、先查个人动态表
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created"))) // 排序
                .skip(index).limit(pageSize); // 分页
        List<Album> albumList = mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);

        // 2、遍历个人动态
        List<Publish> publishList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(albumList)) {
            for (Album album : albumList) {
                // 3、查询动态详情
                Publish publish = mongoTemplate.findById(album.getPublishId(), Publish.class);
                if (publish.getState() == 1) {
                    publishList.add(publish);
                }
            }
        }

        // 查询总记录数
        long counts = mongoTemplate.count(query, Album.class, "quanzi_album_" + userId);

        return new PageBeanVo(pageNum, pageSize, counts, publishList);
    }

    @Override
    public PageBeanVo findTimeLineByPage(Integer pageNum, Integer pageSize, Long userId) {

        // 1、查询时间线表
        Integer index = (pageNum - 1) * pageSize;
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip(index).limit(pageSize);
        List<TimeLine> timeLineList = mongoTemplate.find(query, TimeLine.class, "quanzi_time_line_" + userId);

        // 2、遍历时间线封装动态详情
        List<Publish> publishList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(timeLineList)) {
            for (TimeLine timeLine : timeLineList) {
                Publish publish = mongoTemplate.findById(timeLine.getPublishId(), Publish.class);
                if (publish.getState() == 1) {
                    publishList.add(publish);
                }
            }
        }

        return new PageBeanVo(pageNum, pageSize, 0l, publishList);
    }

    @Override
    public PageBeanVo findRecommendByPage(Integer pageNum, Integer pageSize, Long userId) {
        // 1、查询推荐表
        Integer index = (pageNum - 1) * pageSize;
        Query query = new Query(
                Criteria.where("userId").is(userId)  // 条件
        ).with(Sort.by(Sort.Order.desc("created"))) // 排序
                .skip(index).limit(pageSize); // 分页

        List<RecommendQuanzi> recommendQuanziList = mongoTemplate.find(query, RecommendQuanzi.class);
        // 2、遍历推荐表，封装publish
        List<Publish> publishList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(recommendQuanziList)) {
            for (RecommendQuanzi recommendQuanzi : recommendQuanziList) {
                Publish publish = mongoTemplate.findById(recommendQuanzi.getPublishId(), Publish.class);
                if (publish.getState() == 1) {
                    publishList.add(publish);
                }
            }
        }

        // 3、查询推荐总记录数
        long counts = mongoTemplate.count(query, RecommendQuanzi.class);

        // 4、返回pageBeanVo
        return new PageBeanVo(pageNum, pageSize, counts, publishList);
    }

    @Override
    public Publish findById(String publishId) {
        return mongoTemplate.findById(new ObjectId(publishId), Publish.class);
    }

    @Override
    public PageBeanVo findUserByPage(Integer pageNum, Integer pageSize, Long userId, Integer state) {
        // 条件查询构建
        Query query = new Query().with(Sort.by(Sort.Order.desc("created")))
                .skip((pageNum - 1) * pageSize).limit(pageSize);
        if (userId != null) {

            query.addCriteria(Criteria.where("userId").is(userId));
        }

        if (state != null) { // 状态条件判断
            query.addCriteria(Criteria.where("state").is(state));
        }

        List<Publish> list = mongoTemplate.find(query, Publish.class);
        long count = mongoTemplate.count(query, Publish.class);

        return new PageBeanVo(pageNum, pageSize, count, list);
    }

    @Override
    public void updateState(String pubilshId, Integer state) {
        Query query = new Query(Criteria.where("id").is(new ObjectId(pubilshId)));
        Update update = new Update();
        update.set("state", state);

        mongoTemplate.updateFirst(query, update, Publish.class);
    }

    @Override
    public List<Publish> findByPids(List<Long> pidList) {
        Query query = Query.query(Criteria.where("pid").in(pidList));
        return mongoTemplate.find(query, Publish.class);
    }
}
